<?php

namespace app\admin\controller;

use think\Exception;
use think\facade\View;

class Backup
{

    protected string $mysqldump_bin = 'mysqldump';
    protected string $mysql_bin = 'mysql';
    protected string $name = '备份';
    protected string $table = 'backup';


    function getMysqlBin($bin): string
    {
        $password = env('DB_PASS') ? ' -p' . env('DB_PASS') : '';
        return env('MYSQL_PATH') . $bin . ' -h ' . env('DB_HOST') . ' -P ' . env('DB_PORT') . ' -u ' . env('DB_USER') . ' ' . $password . ' ' . env('DB_NAME');
    }


    function index(): string
    {
        //需要过滤的文件
        $files = array_slice(scandir('backups', 1), 0, -3);
        $list = [];
        if (is_array($files)) {
            foreach ($files as $k => $v) {
                $filesize = filesize('backups/' . $v);
                if ($filesize < 1024) {
                    $size = sprintf("%01.2f", $filesize) . "B";
                } elseif ($filesize < 1024 * 1024) {
                    $size = sprintf("%01.2f", ($filesize / 1024)) . "KB";
                } elseif ($filesize < 1024 * 1024 * 1024) {
                    $size = sprintf("%01.2f", ($filesize / (1024 * 1024))) . "MB";
                } elseif ($filesize < 1024 * 1024 * 1024 * 1024) {
                    $size = sprintf("%01.2f", ($filesize / (1024 * 1024 * 1024))) . "GB";
                }
                $is_del = strstr($v, 'auto') == false ? 1 : 0;
                $list[] = [
                    'file'        => $v,
                    'size'        => $size,
                    'create_time' => filemtime('backups/' . $v),
                    'is_del'      => $is_del,
                ];
            }
        }
        View::assign('list', $list);
        return View::fetch();
    }

    function add($auto = 0): array
    {
        try {
            $path = "backups/";//备份存放路径
            if ($auto == 1) {
                $name = env('DB_NAME') . "_auto_" . date("YmdHis") . ".sql";//备份名称
            } else {
                $name = env('DB_NAME') . "_" . date("YmdHis") . ".sql";//备份名称
            }
            $filePath = $path . $name;
            // 备份命令组合
            $exec = $this->getMysqlBin($this->mysqldump_bin) . ' > ' . $filePath;
            set_time_limit(0);
            exec($exec, $output, $res);

            if ($res != '0') {
                return ['code' => 0, 'message' => '备份失败1'];
            } else {
                return ['code' => 1, 'message' => '备份成功'];
            }
        } catch (Exception $e) {
            return ['code' => 1, 'message' => '备份失败2'];
        }
    }

    public function ossAdd(): array
    {
        try {
            $path = "backups/";
            $name = env('DB_NAME') . "_OssBackup_" . date("Y-m-d_H-i-s") . ".sql";
            $filePath = $path . $name;
            $exec = $this->getMysqlBin($this->mysqldump_bin) . ' > ' . $filePath;
            set_time_limit(0);
            exec($exec, $output, $res);
            if ($res != '0') {
                return ['code' => 0, 'msg' => '备份失败1'];
            } else {
                return ['code' => 1, 'msg' => '备份成功', 'name' => $name, 'path' => $filePath];
            }
        } catch (Exception $e) {
            return ['code' => 1, 'msg' => '备份失败2'];
        }
    }

    /**
     * 还原备份
     * @param $id
     */
    function import($file)
    {

        $sql_file = "backups/" . $file;
        if (!file_exists($sql_file)) return ['code' => '1', 'message' => '文件不存在，请检查', 'icon' => '2'];

        //还原备份前先做一个备份
        $add_res = $this->add();
        if ($add_res['code'] != 1) return ['code' => '0', 'message' => lang('数据备份失败'), 'icon' => '2'];

        //还原备份
        $exec = $this->getMysqlBin($this->mysql_bin) . ' < ' . $sql_file;
        set_time_limit(0);
        exec($exec, $output, $res);

        if ($res != '0') {
            return json(['code' => 0, 'message' => '备份还原']);

        } else {
            return json(['code' => 1, 'message' => '备份还原成功']);

        }
    }

    function delete(array $file)
    {
        foreach ($file as $k => $v) {
            unlink('backups/' . $v);
        }
    }

    /**
     */
    function clear()
    {
        //清空前先备份数据
        $add_res = $this->add();

        if ($add_res['code'] != 1) return ['code' => '0', 'message' => '数据备份失败', 'icon' => '2'];

        $sql_file = app()->getAppPath() . '/clear/clear.sql';
        //还原备份
        $exec = $this->getMysqlBin($this->mysql_bin) . ' < ' . $sql_file;
        set_time_limit(0);
        exec($exec, $output, $res);

        if ($res != '0') {
            return json(['code' => 0, 'message' => '清空失败']);
        } else {
            return json(['code' => 1, 'message' => '已清空']);
        }
    }
}